昨天我們已經按照時間去新增我們的資料了,也得到列表啦,那麼我們今天就要來建立點擊事件,因為如果只有顯示,但是沒辦法到該頁面的話,那就沒辦法聊到天啦,正所謂看得到吃不到,就沒有意義啦!
但是..... 我們會有一個很大的問題就是,當我們今天從A畫面到ChatRoom的時候,我們的資料是從Invitation的資料丟進去的(來源是Firestore),但是如果今天使用者直接想要找我們之前聊過的人聊天呢? 那它不就沒辦法拿到之前的資料啦?
還記得我們昨天有新增一個LastMessage的dataClass嗎? 太棒了,我們就直接從這邊拿到資料吧!!
package com.example.petsmatchingapp.model
data class LastMessage(
val display_name: String = "",
val display_image: String = "",
val display_id: String = "",
val message: String = "",
val send_time: Long? = 0
)
★這裡面的資料都是我們應該要顯示的資訊,所以我們可以透過id來找Firestore相關的照片跟名字(因為我們在寄送訊息的時候會需要accepter的detail),而這些資訊之前是透過invitation的detail來拿到的。
雖然我覺得目前這樣的寫法不是很好,因為這樣代表只要某user拿到其它人的userId,就可以看到它的資訊。之後有空再回來改!!
//一樣想入livedata,好讓我們之後可以觀察
private val _selectedUserDetail = MutableLiveData<User>()
val selectedUserDetail: LiveData<User>
get() = _selectedUserDetail
fun findUserDetailByID(user_id: String){
Firebase.firestore.collection(Constant.USER).document(user_id).get()
.addOnSuccessListener {
_selectedUserDetail.postValue(it.toObject(User::class.java))
}
.addOnFailureListener {
}
}
接下來,我們就回到NotificationAdapter來設定onClick事件。
我們在onBindViewHolder新增
holder.itemView.setOnClickListener {
fragment.goChatRoom(model)
}
並且回到Notification來新增我們的導航跟把LastMessage傳進去viewModel
fun goChatRoom(lastMessage: LastMessage){
chatViewModel.saveSelectedChatRoomUserDetail(lastMessage) findNavController().navigate(R.id.action_navigation_notifications_to_chatRoomFragment)
}
★ 這邊也要記得在我們的Navigation連連看喔,不然找不到ID
來viewModel建立funtion,讓我們儲存UserDetail
private val _selectedChatRoomUserDetail = MutableLiveData<LastMessage>()
val selectedChatRoomUserDetail: LiveData<LastMessage>
get() = _selectedChatRoomUserDetail
fun saveSelectedChatRoomUserDetail(lastMessage: LastMessage){
_selectedChatRoomUserDetail.postValue(lastMessage)
}
然後來到我們的ChatRoomFragment來透過我們的ID,得到我們聊天者的Detail,別忘記要新增判斷喔,不然如果我們的使用者直接從InvitationsDetail進入的話,那我們就拿不到selectedChatRoomUserDetail的值啦!!
if(chatViewModel.fromDetail.value == false){
accountViewModel.findUserDetailByID(chatViewModel.selectedChatRoomUserDetail.value!!.display_id)
}
就跟剛剛提到的一樣,我們從不同Fragment進去的時候,我們的資料來源不一樣,那我們可以怎麼辦呢?!
於是乎,我們就用Flag來判斷,我們首先在ChatViewModel來新增以下
private val _fromDetail = MutableLiveData<Boolean>()
val fromDetail: LiveData<Boolean>
get() = _fromDetail
fun setFromDetailOrNot(boolean: Boolean){
_fromDetail.postValue(boolean)
}
然後再這個兩Fragment來修改它的值,既然它的取名是fromDetail的話,我們當然要在InvitationDetailFragment的時候更改它阿,並且改成true
chatViewModel.setFromDetailOrNot(true)
反之,在NotificationFragment我們把它設成false
基本上如果是從Detail的話,我們就不用修正,但是如果是從NotificationFragment的話,我們就需要作出修正! 我們直接丟剛剛透過點擊事件得到的資料。
修改Read
if (chatViewModel.fromDetail.value == true) {
chatViewModel.messageValueListener(
this,
accountViewModel.userDetail.value!!.id,
matchingViewModel.selectedInvitation.value!!.user_id
)
matchingViewModel.selectedInvitation.value?.user_name?.let {
binding.tvChatRoomAcceptUserName.text = it
}
} else {
chatViewModel.messageValueListener(
this,
accountViewModel.userDetail.value!!.id,
chatViewModel.selectedChatRoomUserDetail.value!!.display_id
)
binding.tvChatRoomAcceptUserName.text = chatViewModel.selectedChatRoomUserDetail.value!!.display_name
}
修改write,我們只要修改來自Notification的資料,並把accept的資料都改成剛剛透過id,找到的Detail。
var message = Message()
if (chatViewModel.fromDetail.value == true){
message = Message(
user_name = accountViewModel.userDetail.value!!.name,
message = binding.edChatRoomInputMessage.text.toString().trim(),
send_user_id = accountViewModel.userDetail.value!!.id,
accept_user_id = matchingViewModel.selectedInvitation.value!!.user_id,
send_user_image = accountViewModel.userDetail.value!!.image,
send_user_name = accountViewModel.userDetail.value!!.name,
time = ServerValue.TIMESTAMP,
accept_user_image = matchingViewModel.selectedInvitation.value?.user_image,
accept_user_name = matchingViewModel.selectedInvitation.value?.user_name
)
}else{
message = Message(
user_name = accountViewModel.userDetail.value!!.name,
message = binding.edChatRoomInputMessage.text.toString().trim(),
send_user_id = accountViewModel.userDetail.value!!.id,
send_user_image = accountViewModel.userDetail.value!!.image,
send_user_name = accountViewModel.userDetail.value!!.name,
accept_user_name = accountViewModel.selectedUserDetail.value!!.name,
accept_user_image = accountViewModel.selectedUserDetail.value!!.image,
accept_user_id = accountViewModel.selectedUserDetail.value!!.id,
time = ServerValue.TIMESTAMP,
)
}
好啦,這樣就大功告成啦!
之前我們是透過Invitation來進入chatRoom,所以我們在InvitationDetaiFragment就已經處理啦,那我們這時候如果直接從NotificationFragment,我們就需要再處理啦!
一樣新增,並在onCreateView呼叫它
private fun dismissActivityActionBarAndBottomNavigationView() {
val activityInstance = this.activity as MatchingActivity
activityInstance.supportActionBar?.hide()
activityInstance.findViewById<BottomNavigationView>(R.id.nav_view).visibility = View.GONE
}
回到NotificationFragment,新增它並且在onResume呼叫它
private fun showActionBarAndBottomNavigation() {
if (requireActivity().findViewById<BottomNavigationView>(R.id.nav_view).visibility == View.GONE) {
requireActivity().findViewById<BottomNavigationView>(R.id.nav_view).visibility =
View.VISIBLE
}
val activityInstance = this.activity as MatchingActivity
activityInstance.supportActionBar?.show()
}
大功告成啦!
成品如下!!